TODO: check for grammar
After almost twelve years of studying music from the optics of a jazz musician, you could say that this has influenced my taste in music and musical analytic capacity by a significant amount. Playing in a bigband twice a week and simply being around a lot of jazz started to consume my being with regards to thinking, listening and of course playing. After a series of unfortunate events, the members of our bigband decided to part ways and around this time I made the most important decision to start paying for a Spotify account. This marks the start of a — heavily influenced by jazz — liked playlist.
Two years go by and the decision is made to go on exchange and have the time of my life. In this period where I was supposed to be studying, I learned to appreciate going out and clubbing with a specific love for minimal techno and deep house music. These styles of music are repetitive and not always the most complex, which wouldn’t have made my heart beat faster in the past. Even so, this new found appreciation for a new style of music must have changed the mean characteristics of a song present in my Spotify liked playlist by a lot.
Because I am aware of this shifting trend in my own music taste, I hope to see this reflected when looking at a deeper analysis of my Spotify liked playlist by using the Spotify API. Since an account’s liked playlist is the only playlist which can not be made public, I’ve had to use a workaround and export my liked playlist as a csv file through a service called Skiley. I could not copy and paste my liked songs to a regular Spotify playlist and export them that way, since the dateAdded feature wouldn’t be preserved that way, which is a most-important feature when performing an analysis over time. The resulting corpus exists of 1338 songs, accumulated over two and a half years of joyous listening.
[1] "addedAt" "albumArtistsNames"
[3] "albumName" "albumPopularity"
[5] "albumRecordLabel" "albumReleaseDate"
[7] "artistFollowers" "artistGenres"
[9] "artistName" "artistPopularity"
[11] "secondaryArtistsNames" "trackDuration"
[13] "trackFeatureAcousticness" "trackFeatureDanceability"
[15] "trackFeatureEnergy" "trackFeatureInstrumentalness"
[17] "trackFeatureKey" "trackFeatureLiveness"
[19] "trackFeatureLoudness" "trackFeatureMode"
[21] "trackFeatureSpeechiness" "trackFeatureTempo"
[23] "trackFeatureTimeSignature" "trackFeatureValence"
[25] "trackName" "trackNumber"
[27] "trackPopularity"
flat beat original spotify:track:7GP1ZmPGH1puBliT9S6Fi5 radio edit spotify:track:5jaVyz2GDdesyu01cBbOSc
TODO: write about the changes over time in tempo and such TODO: make plot pretty
TODO: write song: spotify:track:0zW8R4isqSoK0NdedBnJ80 flangestab by ceephax acid crew
TODO: write
TODO: write
TODO: write
TODO: write
TODO: write In short: completely wrong probs
---
title: "new corpus compMusic"
output:
flexdashboard::flex_dashboard:
# orientation: columns
storyboard: true
social: menu
source: embed
date: "2024-02-23"
editor_options:
markdown:
wrap: sentence
---
```{r setup, include=FALSE}
# knitr::opts_chunk$set(echo = TRUE)
library(flexdashboard)
```
```{r, echo=FALSE}
library(tidyverse)
library(spotifyr)
library(ggplot2)
library(compmus)
df <- read_csv(
"Liked Songs.csv",
show_col_types = FALSE
) %>%
subset(select = -c(
isLocal,
isLikedByUser,
trackIsrc,
trackUrl,
artistUrl,
albumUrl,
albumUpc,
albumType,
addedBy
)) %>%
arrange(addedAt)
df_stats_global <- df %>%
summarise(
mean_speechiness = mean(trackFeatureSpeechiness),
mean_acousticness = mean(trackFeatureAcousticness),
mean_liveness = mean(trackFeatureLiveness),
sd_speechiness = sd(trackFeatureSpeechiness),
sd_acousticness = sd(trackFeatureAcousticness),
sd_liveness = sd(trackFeatureLiveness),
median_speechiness = median(trackFeatureSpeechiness),
median_acousticness = median(trackFeatureAcousticness),
median_liveness = median(trackFeatureLiveness),
mad_speechiness = mad(trackFeatureSpeechiness),
mad_acousticness = mad(trackFeatureAcousticness),
mad_liveness = mad(trackFeatureLiveness)
)
flangestab_raw <- get_tidy_audio_analysis("0zW8R4isqSoK0NdedBnJ80")
flatbeat_raw <- get_tidy_audio_analysis("7GP1ZmPGH1puBliT9S6Fi5")
flatbeat_raw_radioedit <- get_tidy_audio_analysis("5jaVyz2GDdesyu01cBbOSc")
```
Corpus
=========================================
TODO: check for grammar
#### Out with the old: start of a beatiful thing
After almost twelve years of studying music from the optics of a jazz musician, you could say that this has influenced my taste in music and musical analytic capacity by a significant amount.
Playing in a bigband twice a week and simply being around a lot of jazz started to consume my being with regards to thinking, listening and of course playing.
After a series of unfortunate events, the members of our bigband decided to part ways and around this time I made the most important decision to start paying for a Spotify account.
This marks the start of a --- heavily influenced by jazz --- liked playlist.
#### Changes in life and music
Two years go by and the decision is made to go on exchange and have the time of my life.
In this period where I was supposed to be studying, I learned to appreciate going out and clubbing with a specific love for minimal techno and deep house music.
These styles of music are repetitive and not always the most complex, which wouldn't have made my heart beat faster in the past.
Even so, this new found appreciation for a new style of music must have changed the mean characteristics of a song present in my Spotify liked playlist by a lot.
#### Analyse what you like
Because I am aware of this shifting trend in my own music taste, I hope to see this reflected when looking at a deeper analysis of my Spotify liked playlist by using the Spotify API. Since an account's liked playlist is the only playlist which can not be made public, I've had to use a workaround and export my liked playlist as a csv file through a service called *Skiley*.
I could not copy and paste my liked songs to a regular Spotify playlist and export them that way, since the *dateAdded* feature wouldn't be preserved that way, which is a most-important feature when performing an analysis over time.
The resulting corpus exists of 1338 songs, accumulated over two and a half years of joyous listening.
```{r, include=TRUE}
sort(colnames(df))
# sapply(df, class)
```
Visualisations, to be placed {.storyboard}
=========================================
### visualisation safe | fourrier based tempogram
```{r}
flatbeat_raw |>
tempogram(window_size = 8, hop_size = 1, cyclic = TRUE) |>
ggplot(aes(x = time, y = bpm, fill = power)) +
geom_raster() +
scale_fill_viridis_c(guide = "none") +
labs(x = "Time (s)", y = "Tempo (BPM)") +
theme_classic()
```
### visualisation safe \| flatbeat self simil matrix
```{r}
flatbeat <- flatbeat_raw |>
compmus_align(bars, segments) |> # Change `bars`
select(bars) |> # in all three
unnest(bars) |> # of these lines.
mutate(
pitches =
map(segments,
compmus_summarise, pitches,
method = "rms", norm = "euclidean" # Change summary & norm.
)
) |>
mutate(
timbre =
map(segments,
compmus_summarise, timbre,
method = "rms", norm = "euclidean" # Change summary & norm.
)
)
flatbeat |>
compmus_self_similarity(timbre, "cosine") |>
ggplot(
aes(
x = xstart + xduration / 2,
width = xduration,
y = ystart + yduration / 2,
height = yduration,
fill = d
)
) +
geom_tile() +
coord_fixed() +
scale_fill_viridis_c(guide = "none") +
theme_classic() +
labs(x = "", y = "")
```
### visualisation safe \| flatbeat cepstogram
```{r}
flatbeat <- flatbeat_raw |>
compmus_align(bars, segments) |> # Change `bars`
select(bars) |> # in all three
unnest(bars) |> # of these lines.
mutate(
pitches =
map(segments,
compmus_summarise, pitches,
method = "rms", norm = "euclidean" # Change summary & norm.
)
) |>
mutate(
timbre =
map(segments,
compmus_summarise, timbre,
method = "rms", norm = "euclidean" # Change summary & norm.
)
)
flatbeat |>
compmus_gather_timbre() |>
ggplot(
aes(
x = start + duration / 2,
width = duration,
y = basis,
fill = value
)
) +
geom_tile() +
labs(x = "Time (s)", y = NULL, fill = "Magnitude") +
scale_fill_viridis_c() +
theme_classic()
```
### Visualisation safe \| Dynamic Time Warping
```{r}
flatbeat_original <- flatbeat_raw |>
select(segments) |>
unnest(segments) |>
select(start, duration, pitches)
flatbeat_radioedit <- flatbeat_raw_radioedit |>
select(segments) |>
unnest(segments) |>
select(start, duration, pitches)
compmus_long_distance(
flatbeat_original |> mutate(pitches = map(pitches, compmus_normalise, "chebyshev")),
flatbeat_radioedit |> mutate(pitches = map(pitches, compmus_normalise, "chebyshev")),
feature = pitches,
method = "euclidean"
) |>
ggplot(
aes(
x = xstart + xduration / 2,
width = xduration,
y = ystart + yduration / 2,
height = yduration,
fill = d
)
) +
geom_tile() +
coord_equal() +
labs(x = "Flat beat -- Mr. Oizo", y = "Flat beat, radio edit -- Mr. Oizo") +
theme_minimal() +
scale_fill_viridis_c(guide = NULL)
```
***
flat beat original <spotify:track:7GP1ZmPGH1puBliT9S6Fi5> radio edit <spotify:track:5jaVyz2GDdesyu01cBbOSc>
### Visualisation safe \| Chromagrams
```{r}
plt <- df |>
ggplot(
aes(
x = addedAt,
y = trackFeatureTempo,
# color = trackFeatureDanceability,
)
) +
geom_point(size = 1) +
geom_smooth(method = "gam")
plt
```
***
TODO: write about the changes over time in tempo and such TODO: make plot pretty
Analysis {.storyboard}
=========================================
### Chroma Features
```{r}
flangestab <- flangestab_raw |>
select(segments) |>
unnest(segments) |>
select(start, duration, pitches)
flangestab |>
mutate(pitches = map(pitches, compmus_normalise, "euclidean")) |>
compmus_gather_chroma() |>
ggplot(
aes(
x = start + duration / 2,
width = duration,
y = pitch_class,
fill = value
)
) +
geom_tile() +
labs(x = "Time (s)", y = NULL, fill = "Magnitude") +
theme_minimal() +
scale_fill_viridis_c()
```
***
TODO: write
song: <spotify:track:0zW8R4isqSoK0NdedBnJ80>
flangestab by ceephax acid crew
### Structure Analysis and Sef-similarity matrices
***
TODO: write
### Key and Chord Estimation
***
TODO: write
### Novelty Functions and Tempograms
***
TODO: write
### Classification and Clustering
***
TODO: write
# How wrong were my assumptions?
TODO: write In short: completely wrong probs